package com.ciei.dpagm.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.FileCopyUtils;

import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashMap;

/**
 * @author wangyan
 * @since 2023/05/17
 */
public class FormBuilder {

	private static final Logger log = LoggerFactory.getLogger(FormBuilder.class);
	/**
	 * 表单组件默认宽度
	 */
	private static final Integer WIDTH = 24;
	/**
	 * 表单外层结构JSON字符串
	 */
	private static String formJsonStr;
	/**
	 * 单行文本框JSON字符串
	 */
	private static String inputJsonStr;
	/**
	 * 数字框JSON字符串
	 */
	private static String inputNumberJsonStr;
	/**
	 * 下拉选择框JSON字符串
	 */
	private static String selectJsonStr;
	/**
	 * 开关组件JSON字符串
	 */
	private static String switchJsonStr;

	static{
		ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		Resource formResource = resolver.getResource("classpath:json_form/form.json");
		Resource inputResource = resolver.getResource("classpath:json_form/input.json");
		Resource inputNumberResource = resolver.getResource("classpath:json_form/input-number.json");
		Resource selectResource = resolver.getResource("classpath:json_form/select.json");
		Resource switchResource = resolver.getResource("classpath:json_form/switch.json");
		formJsonStr = parseToStr(formResource);
		inputJsonStr = parseToStr(inputResource);
		inputNumberJsonStr = parseToStr(inputNumberResource);
		selectJsonStr = parseToStr(selectResource);
		switchJsonStr = parseToStr(switchResource);
	}

	public static String parseToStr(Resource resource){
		byte[] bytes = new byte[0];
		try (InputStream inputStream = resource.getInputStream()){
			bytes = FileCopyUtils.copyToByteArray(inputStream);
		} catch (IOException e) {
			log.error(e.toString(), e);
		}
		return new String(bytes);
	}

	/**
	 * 获取表单默认布局
	 * @return
	 */
	public static JSONObject getFormObject() {
		return JSONObject.parseObject(formJsonStr);
	}


	/**
	 * 获取单行文本组件对象
	 * @param propertyName
	 * @param propertyKey
	 * @param width
	 * @return
	 */
	public static JSONObject buildInputObject(@NotNull String propertyName, @NotNull String propertyKey, Integer width,Integer propertyDefinitionId) {
		JSONObject inputJSONObject = JSONObject.parseObject(inputJsonStr);
		inputJSONObject.getJSONObject("__config__").fluentPut("label",propertyName).fluentPut("span",width == null ? WIDTH : width).fluentPut("formId",System.nanoTime()).fluentPut("renderKey",String.valueOf(System.nanoTime())).fluentPut("propertyDefinitionId",propertyDefinitionId);
		inputJSONObject.fluentPut("placeholder","请输入" + propertyName).fluentPut("__vModel__",propertyKey);
		return inputJSONObject;
	}

	/**
	 * 获取数字框组件对象
	 * @param propertyName
	 * @param propertyKey
	 * @param width
	 * @return
	 */
	public static JSONObject buildInputNumberObject(@NotNull String propertyName, @NotNull String propertyKey,Integer min,Integer max, Integer width,Integer propertyDefinitionId) {
		JSONObject inputNumberJSONObject = JSONObject.parseObject(inputNumberJsonStr);
		inputNumberJSONObject.getJSONObject("__config__").fluentPut("label",propertyName).fluentPut("span",width == null ? WIDTH : width).fluentPut("formId",System.nanoTime()).fluentPut("renderKey",String.valueOf(System.nanoTime())).fluentPut("propertyDefinitionId",propertyDefinitionId);
		inputNumberJSONObject.fluentPut("placeholder","请输入" + propertyName).fluentPut("__vModel__",propertyKey);
		if (min != null){
			inputNumberJSONObject.put("min",min);
		}
		if (max != null){
			inputNumberJSONObject.put("max",max);
		}
		return inputNumberJSONObject;
	}

	/**
	 * 获取下拉选择框组件对象
	 * @param propertyName
	 * @param propertyKey
	 * @param width
	 * @param optionMap
	 * @return
	 */
	public static JSONObject buildSelectObject(@NotNull String propertyName, @NotNull String propertyKey, Integer width, LinkedHashMap<String,String> optionMap,Integer propertyDefinitionId) {
		JSONObject selectJSONObject = JSONObject.parseObject(selectJsonStr);
		selectJSONObject.getJSONObject("__config__").fluentPut("label",propertyName).fluentPut("span",width == null ? WIDTH : width).fluentPut("formId",System.nanoTime()).fluentPut("renderKey",String.valueOf(System.nanoTime())).fluentPut("propertyDefinitionId",propertyDefinitionId);
		selectJSONObject.fluentPut("placeholder","请选择" + propertyName).fluentPut("__vModel__",propertyKey);
		JSONArray options = selectJSONObject.getJSONObject("__slot__").getJSONArray("options");
		optionMap.forEach((key,value)->{
			JSONObject option = new JSONObject();
			option.put("label",key);
			option.put("value",value);
			options.add(option);
		});
		return selectJSONObject;
	}

	/**
	 * 获取开关组件对象
	 * @param propertyName
	 * @param propertyKey
	 * @param width
	 * @return
	 */
	public static JSONObject buildSwitchObject(@NotNull String propertyName, @NotNull String propertyKey, Integer width,Integer propertyDefinitionId) {
		JSONObject switchJSONObject = JSONObject.parseObject(switchJsonStr);
		switchJSONObject.getJSONObject("__config__").fluentPut("label",propertyName).fluentPut("span",width == null ? WIDTH : width).fluentPut("formId",System.nanoTime()).fluentPut("renderKey",String.valueOf(System.nanoTime())).fluentPut("propertyDefinitionId",propertyDefinitionId);
		switchJSONObject.fluentPut("__vModel__",propertyKey);
		return switchJSONObject;
	}

	/**
	 * 添加组件
	 * @param componentArray
	 * @return
	 */
	public static JSONObject addFormComponents(JSONArray componentArray){
		JSONObject formObject = getFormObject();
		JSONArray fields = formObject.getJSONArray("fields");
		fields.addAll(componentArray);
		return formObject;
	}
}
